#pragma once

#include <QObject>
#include <QVariant>
#include <QFile>
#include <QThread>
#include <QMutex>

class RemoteTableModel;

/**
 * @brief 用于处理图片上传的工作类，支持从文件路径或直接从内存数据上传图片
 *
 * 该类设计为在单独的线程中运行，使用信号和槽机制与主线程通信
 */
class ImageUploadWorker : public QObject
{
    Q_OBJECT
public:
    /**
     * @brief 图片上传配置结构体
     */
    struct UploadConfig
    {
        QString foreignKeyField;  // 外键字段名（如 "dzcs_id"），用于关联图片与其他数据
        QVariant foreignKeyValue; // 外键值
        QString imageUrlField;    // 图片URL字段名，用于存储图片上传后的URL
        QVariantMap fixedFields;  // 固定字段（content/result/time等），会添加到每条图片记录中
    };

    /// @brief  路径模式构造函数，从文件路径上传图片
    /// @param imagemodel 远程表格模型，用于数据库操作
    /// @param imagePaths 图片文件路径列表
    /// @param config 上传配置
    /// @param parent 父对象
    ImageUploadWorker(RemoteTableModel *imagemodel,
                      const QStringList &imagePaths,
                      const UploadConfig &config,
                      QObject *parent = nullptr);

    /// @brief  直接传入图片数据构造函数，从内存数据上传图片
    /// @param imagemodel 远程表格模型，用于数据库操作
    /// @param imageDataList 图片数据列表
    /// @param imageIdentifiers 图片标识符列表，用于标识每张图片
    /// @param config 上传配置
    /// @param parent 父对象
    ImageUploadWorker(RemoteTableModel *imagemodel,
                      const QList<QByteArray> &imageDataList,
                      const QList<QString> &imageIdentifiers,
                      const UploadConfig &config,
                      QObject *parent = nullptr);

public slots:
    /**
     * @brief 开始上传所有图片
     *
     * 根据构造函数传入的参数，选择处理文件路径列表或图片数据列表
     */
    void startUpload();

signals:
    /**
     * @brief 所有图片上传完成时发出的信号
     */
    void finished();

    /**
     * @brief 单张图片上传成功时发出的信号
     * @param identifier 图片标识符
     * @param url 图片上传后的URL
     */
    void imageUploaded(const QString &identifier, const QString &url);

    /**
     * @brief 单张图片上传失败时发出的信号
     * @param identifier 图片标识符
     * @param error 错误信息
     */
    void imageFailed(const QString &identifier, const QString &error);

private:
    /**
     * @brief 处理来自文件路径的图片
     * @param imagePath 图片文件路径
     */
    void processImageFromPath(const QString &imagePath);

    /**
     * @brief 处理来自内存的图片数据
     * @param imageData 图片数据
     * @param identifier 图片标识符
     */
    void processImageData(const QByteArray &imageData, const QString &identifier);

    /**
     * @brief 实际执行图片上传的函数
     * @param imageData 图片数据
     * @param identifier 图片标识符
     */
    void uploadImageData(const QByteArray &imageData, const QString &identifier);

    /**
     * @brief 将图片URL保存到数据库
     * @param identifier 图片标识符
     * @param url 图片URL
     */
    void saveImageToDatabase(const QString &identifier, const QString &url);

    /**
     * @brief 从文件路径读取图片数据
     * @param imagePath 图片文件路径
     * @return 图片数据，如果读取失败则返回空字节数组
     */
    QByteArray getImageData(const QString &imagePath);

private:
    RemoteTableModel *m_imagemodel; // 远程表格模型，用于数据库操作

    QStringList m_imagePaths;          // 图片路径模式，存储图片文件路径列表
    QList<QByteArray> m_imageDataList; // 原始数据模式，存储图片数据列表
    QList<QString> m_imageIdentifiers; // 原始数据的标识符列表

    UploadConfig m_config; // 上传配置
};

class ImageUploadManager
{
public:
    static void startImageUpload(
        RemoteTableModel *imagemodel,
        const QStringList &imagePaths,
        const ImageUploadWorker::UploadConfig &config,
        QObject *parent = nullptr,
        std::function<void(const QString &, const QString &)> onUploaded = nullptr,
        std::function<void(const QString &, const QString &)> onFailed = nullptr)
    {

        QThread *uploadThread = new QThread(parent);
        QMutexLocker locker(&threadMutex);
        activeThreads.append(uploadThread);
        ImageUploadWorker *worker = new ImageUploadWorker(imagemodel, imagePaths, config);
        worker->moveToThread(uploadThread);

        // 线程管理连接
        QObject::connect(uploadThread, &QThread::started, worker, &ImageUploadWorker::startUpload);
        QObject::connect(worker, &ImageUploadWorker::finished, uploadThread, &QThread::quit);
        QObject::connect(worker, &ImageUploadWorker::finished, worker, &QObject::deleteLater);
        QObject::connect(uploadThread, &QThread::finished, uploadThread, &QObject::deleteLater);

        // 结果回调
        if (onUploaded)
        {
            QObject::connect(worker, &ImageUploadWorker::imageUploaded,
                             [onUploaded](const QString &id, const QString &url)
                             {
                                 onUploaded(id, url);
                             });
        }

        if (onFailed)
        {
            QObject::connect(worker, &ImageUploadWorker::imageFailed,
                             [onFailed](const QString &id, const QString &error)
                             {
                                 onFailed(id, error);
                             });
        }

        uploadThread->start();
        // 连接线程结束信号
        QObject::connect(uploadThread, &QThread::finished, [uploadThread]()
                         {
        QMutexLocker locker(&threadMutex);
        activeThreads.removeOne(uploadThread); });
    }

    static void startImageUpload(
        RemoteTableModel *imagemodel,
        const QList<QByteArray> &imageDataList,
        const QList<QString> &imageIdentifiers,
        const ImageUploadWorker::UploadConfig &config,
        QObject *parent = nullptr,
        std::function<void(const QString &, const QString &)> onUploaded = nullptr,
        std::function<void(const QString &, const QString &)> onFailed = nullptr)
    {
        QThread *uploadThread = new QThread(parent);
        QMutexLocker locker(&threadMutex);
        activeThreads.append(uploadThread);
        ImageUploadWorker *worker = new ImageUploadWorker(imagemodel, imageDataList, imageIdentifiers, config);
        worker->moveToThread(uploadThread);

        // 线程管理连接
        QObject::connect(uploadThread, &QThread::started, worker, &ImageUploadWorker::startUpload);
        QObject::connect(worker, &ImageUploadWorker::finished, uploadThread, &QThread::quit);
        QObject::connect(worker, &ImageUploadWorker::finished, worker, &QObject::deleteLater);
        QObject::connect(uploadThread, &QThread::finished, uploadThread, &QObject::deleteLater);

        // 结果回调
        if (onUploaded)
        {
            QObject::connect(worker, &ImageUploadWorker::imageUploaded,
                             [onUploaded](const QString &id, const QString &url)
                             {
                                 onUploaded(id, url);
                             });
        }
        if (onFailed)
        {
            QObject::connect(worker, &ImageUploadWorker::imageFailed,
                             [onFailed](const QString &id, const QString &error)
                             {
                                 onFailed(id, error);
                             });
        }
        uploadThread->start();
        // 连接线程结束信号
        QObject::connect(uploadThread, &QThread::finished, [uploadThread]()
                         {
        QMutexLocker locker(&threadMutex);
        activeThreads.removeOne(uploadThread); });
    }
    // 添加线程管理方法-主界面析构函数调用
    static void stopAllUploads()
    {
        QMutexLocker locker(&threadMutex);
        for (QThread *thread : activeThreads)
        {
            if (thread && thread->isRunning())
            {
                thread->quit();
                thread->wait(100); // 等待100ms线程退出
            }
        }
        activeThreads.clear();
    }

private:
    static QList<QThread *> activeThreads;
    static QMutex threadMutex;
};
